import bufferOverlay from "@/components/LayerTool/modules/buffer-overlay.vue";
import { createApp, h } from "vue";
function MeasureBuffer({ map, bufferRadius = 1, mittBus }) {
  const ins = MeasureBuffer.getIns();
  if (ins) {
    return ins
  }
  this.map = map;
  this.bufferRadius = bufferRadius;
  this.mittBus = mittBus;
  this.listener = null;
  this.overlayLimit = 1;
  this.overlaysArr = [];
  this.sourceVec = null;
  this.layerPoint = null;
  this.styleVec = null;
  this.overlayForLocate = {
    overlay: null,
    app: null,
    size: true,
    detail: true
  };
  this.init();
  MeasureBuffer.ins = this;
}
MeasureBuffer.getIns = function () {
  return MeasureBuffer.ins;
}
MeasureBuffer.create = function ({ map, bufferRadius, mittBus }) {
  return new MeasureBuffer({ map, bufferRadius, mittBus })
}
// 初始化
MeasureBuffer.prototype.init = function () {
  if (!ol) { return }
  if (!this.map) { return }
  // 矢量数据源
  this.sourceVec = new ol.source.Vector();
  this.layerPoint = new ol.layer.Vector({
    source: this.sourceVec
  });
  // 矢量样式
  this.styleVec = new ol.style.Style({
    stroke: new ol.style.Stroke({
      color: 'rgba(255, 87, 34, 1)',
      width: 2
    }),
    fill: new ol.style.Fill({
      color: 'rgba(255, 87, 34, 0.5)'
    })
  });
  this.layerPoint.setZIndex(21);
  this.map.addLayer(this.layerPoint);

  // 初始化绑定事件
  this.bindEvt();
}
// 绑定事件
MeasureBuffer.prototype.bindEvt = function () {
  this.map.getViewport().style.cursor = 'pointer';
  this.listener = this.map.on('click', (e) => {
    this.putOverlay(e);
  })
}
// 添加overlay
MeasureBuffer.prototype.putOverlay = function (e) {
  const this_ = this;
  if (this.overlaysArr.length >= this.overlayLimit) {
    const head = this.overlaysArr[0];
    this.clearSingleOverlay(head);
    this.overlaysArr.shift();
  }

  this.clearLocateOverlay();
  const coordinate = e.coordinate;
  if (!coordinate) { return }
  const [longitude, latitude] = coordinate;
  if (!longitude || !latitude) { return }
  const unid = new Date().getTime()
  const attrIns = this;
  const app = createApp({
    render() {
      return h(bufferOverlay, {
        unid,
        onlyLocate: true,
        onClose: (e) => {
          const { unid } = e;
          for (let i = 0; i < attrIns.overlaysArr.length; i++) {
            const item = attrIns.overlaysArr[i];
            if (item.id === unid) {
              attrIns.clearSingleOverlay(item);
              attrIns.overlaysArr.splice(i, 1);
              break;
            }
          }
        }
      })
    }
  })
  // 暂时不用
  // app.onUnmount()
  const parent = document.createElement('div');
  const el = app.mount(parent).$el;
  // 创建Overlay
  const overlay = new ol.Overlay({
    id: unid,
    element: el,
    offset: [0, -45],
    positioning: 'bottom-center',
    insertFirst: false,
    stopEvent: true
  });
  const geometryCircle = new ol.geom.Circle(ol.proj.transform(coordinate, 'EPSG:4326', 'EPSG:3857'), this.bufferRadius, 'XY')
    .transform('EPSG:3857', 'EPSG:4326')
  // 绘制圆
  // 添加径向的渐变
  const featureVector = new ol.Feature({
    geometry: geometryCircle
  });
  this.mittBus && this.mittBus.emit('polygon', {
    polygon: ol.geom.Polygon.fromCircle(geometryCircle),
    isFresh: true
  })
  // featureVector.setStyle(this.styleVec);
  featureVector.setStyle(new ol.style.Style({
    renderer(coordinates, state) {
      const [[x, y], [x1, y1]] = coordinates;
      const ctx = state.context;
      const dx = x1 - x;
      const dy = y1 - y;
      const radius = Math.sqrt(dx * dx + dy * dy);
      const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius);
      gradient.addColorStop(0.0, 'rgba(0, 255, 255,0)');
      gradient.addColorStop(0.2, 'rgba(0, 255, 255,0.01)');
      gradient.addColorStop(0.4, 'rgba(0, 255, 255,0.04)');
      gradient.addColorStop(0.6, 'rgba(0, 255, 255,0.09)');
      gradient.addColorStop(0.8, 'rgba(0, 255, 255,0.16)');
      gradient.addColorStop(1.0, 'rgba(0, 255, 255,0.25)');

      ctx.save();
      ctx.beginPath();
      ctx.arc(x, y, radius, 0, 2 * Math.PI, true);
      ctx.fillStyle = gradient;
      ctx.fill();
      ctx.arc(x, y, radius, 0, 2 * Math.PI, true);
      ctx.strokeStyle = 'rgba(0, 255, 255,0.64)';
      ctx.setLineDash([5, 10]);
      ctx.lineWidth = 2;
      ctx.stroke();
      ctx.closePath();

      // 绘制半径标线
      ctx.beginPath();
      ctx.moveTo(x, y);
      let angle = Math.PI / 3;
      ctx.lineTo(x + radius * Math.cos(angle), y - radius * Math.sin(angle));
      ctx.lineWidth = 3;
      ctx.strokeStyle = 'rgba(255, 235, 59, 0.9)';
      ctx.lineCap = 'round';
      ctx.stroke();
      ctx.closePath();
      ctx.restore();

      //  绘制文本
      ctx.save();
      ctx.beginPath();
      ctx.translate(radius / 4, -radius / 4);
      ctx.font = `bold ${radius / 7}px 'ALIBABAPUHUI-REGU'`;
      ctx.textBaseline = "middle";
      ctx.fillStyle = 'rgba(255, 235, 59, 1)';
      ctx.strokeStyle = 'rgba(255, 255, 255, 1)';
      ctx.fillText(`R=${this_.bufferRadius}M`, x, y);
      // if (this_.bufferRadius > 50) {
      //   ctx.strokeText(`R=${this_.bufferRadius}M`, x, y);
      // }
      ctx.closePath();
      ctx.restore();
    }
  }));
  this.sourceVec.addFeature(featureVector);

  this.map.addOverlay(overlay); // 将Overlay添加到地图
  overlay.setPosition(coordinate); // 设置Overlay的位置
  this.overlaysArr.push({
    id: unid,
    app,
    overlay,
    featureVector
  });
}
// MeasureBuffer.prototype.showDetail = function ({ detail }) {
//   if (this.overlayForLocate.app) {
//     this.overlayForLocate.app.message = 'Apple'
//   }
// }
// 添加用于定位的 overlay
MeasureBuffer.prototype.setOverlayForLocate = function ({ coordinate, listData }) {
  if (this.overlayForLocate.overlay) {
    this.overlayForLocate.overlay.setPosition(coordinate);
  }
  const attrIns = this;
  const unid = new Date().getTime();
  const app = createApp({
    render() {
      return h(bufferOverlay, {
        unid,
        mainTitle: "详细信息",
        propsType: "green",
        listData,
        onlyLocate: false,
        size: attrIns.overlayForLocate.size,
        detail: attrIns.overlayForLocate.detail,
        unid,
        onClose: (e) => {
        },
        onSize: (e) => {
          attrIns.overlayForLocate.size = e;
        },
        onDetail: (e) => {
          attrIns.overlayForLocate.detail = e;
        },
      });
    }
  });

  const parent = document.createElement('div');
  const el = app.mount(parent).$el;

  if (this.overlayForLocate.app) {
    this.overlayForLocate.app.unmount();
    this.overlayForLocate.overlay.setElement(el);
    this.overlayForLocate.app = app;
    return
  }

  // 创建Overlay
  const overlay = new ol.Overlay({
    id: unid,
    element: el,
    offset: [0, -45],
    positioning: 'bottom-center',
    insertFirst: false,
    stopEvent: true
  });
  this.map.addOverlay(overlay);
  overlay.setPosition(coordinate);
  this.overlayForLocate.overlay = overlay;
  this.overlayForLocate.app = app;
}
// 重新设置半径
MeasureBuffer.prototype.resetRadius = function ({ radius }) {
  this.clearLocateOverlay();

  this.bufferRadius = radius
  for (let i = 0; i < this.overlaysArr.length; i++) {
    const item = this.overlaysArr[i];
    const featureVector = item.featureVector;
    const coordinate = featureVector.getGeometry().getCenter();
    if (featureVector && coordinate) {
      const geometryCircle = new ol.geom.Circle(ol.proj.transform(coordinate, 'EPSG:4326', 'EPSG:3857'), radius, 'XY')
        .transform('EPSG:3857', 'EPSG:4326')
      featureVector.setGeometry(geometryCircle);
      this.mittBus && this.mittBus.emit('polygon', {
        polygon: ol.geom.Polygon.fromCircle(geometryCircle),
        isFresh: true
      })
    }
  }
}
// 清除单个
MeasureBuffer.prototype.clearSingleOverlay = function (item) {
  item.app.unmount();
  this.map.removeOverlay(item.overlay);
  this.sourceVec.removeFeature(item.featureVector);
}
// 清除所有
MeasureBuffer.prototype.clearAllOverlay = function () {
  const arr = this.overlaysArr;
  if (arr.length) {
    for (let i = 0; i < arr.length; i++) {
      const item = arr[i];
      this.clearSingleOverlay(item);
    }
    this.overlaysArr = [];
  }
}
// 
MeasureBuffer.prototype.clearLocateOverlay = function() {
  if(this.overlayForLocate.overlay) {
    this.map.removeOverlay(this.overlayForLocate.overlay);
    this.overlayForLocate.overlay = null;
  }
  if(this.overlayForLocate.app) {
    this.overlayForLocate.app.unmount();
    this.overlayForLocate.app = null;
  }
}
// 销毁实例
MeasureBuffer.prototype.destroy = function () {
  ol.Observable.unByKey(this.listener);
  this.listener = null;
  this.clearAllOverlay();
  this.clearLocateOverlay();
  this.map.getViewport().style.cursor = 'inherit';
  this.mittBus && this.mittBus.all.clear();
  MeasureBuffer.ins = null;
}
export default MeasureBuffer